package com.leyou.item.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leyou.common.dto.PageDTO;
import com.leyou.common.exception.LyException;
import com.leyou.item.dto.CategoryDTO;
import com.leyou.item.dto.SpuDTO;
import com.leyou.item.entitry.Brand;
import com.leyou.item.entitry.Sku;
import com.leyou.item.entitry.Spu;
import com.leyou.item.entitry.SpuDetail;
import com.leyou.item.mapper.BrandMapper;
import com.leyou.item.mapper.CategoryMapper;
import com.leyou.item.mapper.SpuMapper;
import com.leyou.item.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class SpuServiceImpl extends ServiceImpl<SpuMapper, Spu> implements SpuService {
    @Autowired
    private SpuMapper spuMapper;

   @Autowired
   private CategoryMapper categoryMapper;

   @Autowired
   private BrandMapper brandMapper;

   @Autowired
   private SpuDetailService spuDetailService;

   @Autowired
   private SkuService skuService;

    @Autowired
    private SpuService spuService;


    @Override
    public PageDTO<SpuDTO> listSpuByPage(Integer page, Integer rows, Boolean saleable, Long categoryId, Long brandId, Long id) {
        int current = Math.max(page, 1);
        int size = Math.max(rows, 5);
        IPage<Spu> result=query()
                .eq(saleable!=null,"saleable",saleable)
                .eq(categoryId!=null,"categoryId",categoryId)
                .eq(brandId!=null,"brandId",brandId)
                .eq(id != null,"id", id)
                .page(new Page<>(current,size));
        long total = result.getTotal();
        long pages = result.getPages();
        List<Spu> recordsList = result.getRecords();
        List<SpuDTO> spuDTOList = SpuDTO.convertEntityList(recordsList);


        spuDTOList.stream().forEach(spuDTO -> {

            spuDTO.setBrandName(this.brandMapper.selectOne(new QueryWrapper<Brand>().eq("id",spuDTO.getBrandId())).getName());
            List<Long> categoryIds = spuDTO.getCategoryIds();

            String collectNames = this.listCategorySoftByIds(spuDTO.getCategoryIds())
                    .stream()
                    .map(CategoryDTO::getName)
                    .collect(Collectors.joining("/"));

            spuDTO.setCategoryName(collectNames);
        });

        PageDTO<SpuDTO> spuDTOPageDTO = new PageDTO<SpuDTO>(total, pages,spuDTOList);


        return spuDTOPageDTO;
    }

    @Override
    public List<SpuDTO> listSpuById(Long id) {
        List<Spu> spuByIdList = this.spuMapper.selectList(new QueryWrapper<Spu>().eq("id", id));
       return  SpuDTO.convertEntityList(spuByIdList);
    }

    @Override
    public List<SpuDTO> listSpuWithSkuWithSpuDetail(Long id) {
        List<SpuDTO> spuDTOList = this.spuMapper.listSpuWithSkuWithSpuDetail(id);

//       spuDTOList.stream().forEach(spuDTO -> {
//           spuDTO.getCid1();
//           spuDTO.getCid2();
//           spuDTO.getCid3();
//       });

        return spuDTOList;
    }

    @Override
    public List<CategoryDTO> listCategorySoftByIds(List<Long> ids) {

        List selectBatchIds = categoryMapper.selectBatchIds(ids);
        return CategoryDTO.converEntity(selectBatchIds);
    }

    @Override
    @Transactional
    public void addGoods(SpuDTO spuDTO) {

        //1.添加spu
        Spu spu = spuDTO.toEntity(Spu.class);
        this.save(spu);

        //2.添加spu详情
        SpuDetail spuDetail = spuDTO.getSpuDetail().toEntity(SpuDetail.class);
        spuDetail.setSpuId(spu.getId());
        boolean save = this.spuDetailService.save(spuDetail);
        if (!save){
            throw new LyException(500,"新增商品失败");
        }

        //3.添加sku
        List<Sku> skusList = spuDTO.getSkus().stream().map(skuDTO -> {
            Sku sku = skuDTO.toEntity(Sku.class);
            sku.setSaleable(false);
            sku.setSpuId(spu.getId());
            return sku;
        }).collect(Collectors.toList());

        this.skuService.saveBatch(skusList);

    }

    @Override
    public void updateGoodssaleable(Long spuId, Boolean saleable) {
        Spu spu = new Spu();
        spu.setId(spuId);
        spu.setSaleable(saleable);
        this.spuService.updateById(spu);

        Sku sku = new Sku();
        sku.setSaleable(saleable);
        this.skuService.update(sku,new QueryWrapper<Sku>().eq("spu_id",spuId));

    }

    @Override
    @Transactional
    public void updateGoods(SpuDTO spuDTO) {
        //判断，想要修改什么

        //要修改spu
        if (spuDTO.getId()!=null){
                this.spuService.updateById(spuDTO.toEntity(Spu.class));
        }

        //要删除

        if (null!= spuDTO.getSpuDetail()){
                this.spuDetailService.updateById(spuDTO.getSpuDetail().toEntity(SpuDetail.class));

        }

        //要添加,删除，修改
        if (!CollectionUtils.isEmpty(spuDTO.getSkus())){
                List<Sku>  toAdd =new ArrayList<>();
                List<Sku>  toDelete =new ArrayList<>();
                List<Sku>  toUpdate =new ArrayList<>();

           spuDTO.getSkus().forEach(skuDTO -> {
               Sku sku = skuDTO.toEntity(Sku.class);

               if (sku.getId()==null){
                   toAdd.add(sku);
               }else if (sku.getSaleable()==null){
                   toUpdate.add(sku);
               }else {
                    toDelete.add(sku);
               }

               if (!CollectionUtils.isEmpty(toAdd)){
                   this.skuService.saveBatch(toAdd);
               }
               if (!CollectionUtils.isEmpty(toDelete)){
                   this.skuService.removeByIds(toDelete.stream().map(Sku::getId).collect(Collectors.toList()));
               }
               if (!CollectionUtils.isEmpty(toUpdate)){
                   this.skuService.updateBatchById(toUpdate);
               }
           });

        }

    }
}